To reduce the ageified model to the case of homogenous mixing, we need to set:
In other words, we need to have a uniform population distribution and uniform contact structure.
There is a test (in tests/testthat/test-ageify.R) that includes a check to ensure that the homogeneous case of the age-structured model reduces down to the base simulation.
Full age-structured results:
A diagonal contact matrix decouples the age-specific epidemics entirely.
There is a test checking that identical epidemics are generated within each age group with a diagonal contact matrix and a uniform population distribution.
A “compound” contact matrix keeps the majority of contacts within an age-group, and contacts outside of an age group are uniformly distributed across all other age groups. It’s essentially the diagonal contact matrix + the uniform contact matrix (row-normalized).
The epidemics look identical, which is unsurprising given \((\beta_0)_i\), \(I_i(0)\), and the distribution \(p_{ij}\) are identical for all \(i\).
## [1] "beta0:"
## [1] 2.0 3.0 1.5
## [1] "pmat:"
## 0-29 30-59 60+
## 0-29 0.4000000 0.2000000 0.4000000
## 30-59 0.1333333 0.7666667 0.1000000
## 60+ 0.5333333 0.2000000 0.2666667
## [1] "balance condition implies the following matrix should be symmetric:"
## 0-29 30-59 60+
## 0-29 4e+06 2000000 4000000
## 30-59 2e+06 11500000 1500000
## 60+ 4e+06 1500000 2000000
## [1] "is symmetric?"
## [1] TRUE
## [1] "beta0:"
## [1] 1 2 3
## [1] "pmat:"
## 0-29 30-59 60+
## 0-29 0.4000000 0.2000000 0.4000000
## 30-59 0.1333333 0.7666667 0.1000000
## 60+ 0.5333333 0.2000000 0.2666667
## [1] "balance condition implies the following matrix should be symmetric:"
## 0-29 30-59 60+
## 0-29 4e+06 2000000 4000000
## 30-59 2e+06 11500000 1500000
## 60+ 4e+06 1500000 2000000
## [1] "is symmetric?"
## [1] TRUE
Here’s a demo using the Mistry et al. contact matrix for Ontario with default (pre-pandemic) contact structure:
Assuming work contacts are halved, school and community contacts are turned off:
Looking at the code for time-varying params (notes in IP_explore_codebase), it should just work for ageified transmission. Let’s try that here, comparing the base model’s results with the equivalent homogeneous case of the ageified model. We’ll intervene early in the epidemic by taking 1/4 of the original transmission rate, then bumping it up to 3x the original value a few weeks later:
## [1] "comparing base and ageified simulation results... equal?"
## [1] TRUE
It’s a perfect match! The time-dependent update to beta is working in the ageified model. Let’s check that this is still true, even if beta0 varies by age, with all else equal (uniform):
## [1] "comparing base and ageified simulation results... equal?"
## [1] TRUE
## [1] "comparing base and ageified simulation results... equal?"
## [1] "Component \"S\": Mean relative difference: 0.002955364"
## [2] "Component \"E\": Mean relative difference: 0.026857"
## [3] "Component \"Ia\": Mean relative difference: 0.01728503"
## [4] "Component \"Ip\": Mean relative difference: 0.02534264"
## [5] "Component \"Im\": Mean relative difference: 0.01692353"
## [6] "Component \"Is\": Mean relative difference: 0.01813194"
## [7] "Component \"H\": Mean relative difference: 0.01203807"
## [8] "Component \"H2\": Mean relative difference: 0.007901123"
## [9] "Component \"ICUs\": Mean relative difference: 0.008638529"
## [10] "Component \"ICUd\": Mean relative difference: 0.01309579"
## [11] "Component \"D\": Mean relative difference: 0.003606326"
## [12] "Component \"R\": Mean relative difference: 0.00314047"
## [13] "Component \"X\": Mean relative difference: 0.003080081"
Though it’s hard to see from the aggregate plots, the last fig shows the subtle differences in all outcomes introduced by taking a different
beta0 by age, and it clearly shows that time-varying beta0 is having an effect.